Skip to content

feat(tui,coding-agent): show working/idle agent status in terminal tabs - #1397

Open
MoerAI wants to merge 2 commits into
code-yeongyu:mainfrom
MoerAI:feat/terminal-tab-agent-status
Open

feat(tui,coding-agent): show working/idle agent status in terminal tabs#1397
MoerAI wants to merge 2 commits into
code-yeongyu:mainfrom
MoerAI:feat/terminal-tab-agent-status

Conversation

@MoerAI

@MoerAI MoerAI commented Sep 5, 2026

Copy link
Copy Markdown

What

The interactive mode prefixes the terminal title with [working] on agent_start and compaction_start, restoring the plain title on agent_end, compaction_end, and stop.

The token leads the title so it survives tab truncation. Idle uses the plain title. Updates are static and event-driven.

Scope: packages/coding-agent. The existing OSC title transport is unchanged.

Tests

The regression tests exercise handleEvent for agent start/end, compaction start/end, compaction during streaming, and stop(). They also cover title composition, repeated transitions, and preservation of process.title.

Removing the event wiring makes 6 of the 9 regression tests fail.

Verification:

  • Coding-agent tests passed with no failures.
  • TUI tests: 735 passed.
  • npm run check: passed.

QA evidence

Artifacts: local-ignore/qa-evidence/20260906-terminal-tab-agent-status/.

The real senpi TUI ran in a node-pty terminal against a local fake model server, in an isolated sandbox without paid model calls. The real ~/.senpi/agent/auth.json hash was unchanged.

The driver subscribes to PTY output. The fake server holds its response until the working title is observed, then releases the response so completion and return to idle can be checked without fixed sleeps or polling.

Observed OSC title transitions:

senpi - work
[working] senpi - work
senpi - work

results.json: {"passed":7,"total":7,"allPassed":true}.

This verifies the emitted title sequence through the real CLI and PTY. Individual terminal applications were not separately driven.

No regression

Title precedence remains active tool hook > tool execution > extension > normal title. The working token is prepended without changing the title content. The existing terminal progress setting and OSC title transport remain unchanged.

Terminal tabs gave no signal about whether a senpi session was busy or
waiting for input, so users had to focus each tab to find out.

Emit an event-driven status instead of a spinner (Codex's animated title
spins bells under screen and does not animate in tmux, openai/codex#17198):

- tui: setTitle() now emits OSC 2 alongside OSC 0. OSC 2 is the sequence
  Zed documents for terminal titles and tmux/screen derive window names
  from it, so titles reach more terminals. Extracted as
  formatTerminalTitleSequence().
- coding-agent: track agent activity and prefix the terminal title with
  "[working]" on agent_start/compaction_start, returning to the plain
  title on agent_end/compaction_end/stop. The token leads the title so it
  survives the truncation tab bars apply.
- coding-agent: mirror the status into process.title, since Zed builds
  its tab label from the foreground process (name + argv), not from OSC.

Known limitation: on macOS process.title rewrites argv only (p_comm and
proc_pidpath stay "node"), and Zed's pty_info has_changed compares only
cwd and name, so Zed will not repaint a tab from an argv-only change. The
refreshed argv is still cached, so the tab picks it up on the next
repaint. The OSC title reaches Zed breadcrumbs and other terminals' tabs
immediately.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T18:45:48.382548Z 9d515f0 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d515f03e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

* from the OSC title, so argv is the only channel that can reach that label.
*/
private applyProcessActivityTitle(): void {
process.title = formatAgentActivityProcessTitle(this.agentActivityStatus, APP_NAME);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Put the status in an argv element Zed reads

When this runs under Zed, assigning process.title rewrites the OS command line as a single argv[0] value such as senpi [working]. The Zed path described here builds the tab label from the executable name plus argv[1..], so neither status token is included; the added test only reads Node's process.title getter and therefore cannot detect this. Consequently the channel introduced specifically for Zed tabs does not surface the status and needs to use data Zed actually reads.

Useful? React with 👍 / 👎.

Review follow-up on the working/idle terminal status.

Revert the tui OSC 2 change. The terminal parser Zed/Alacritty use
dispatches OSC `0 | 2` to the same set_title handler (alacritty/vte
osc_dispatch), so OSC 0 already set the title and the extra sequence and
its exported helper were redundant. packages/tui is now untouched.

Drop the process.title mirror. Measured against the installed Zed 1.18.1
(tag v1.18.1) and a KERN_PROCARGS2 probe: Zed renders `name + argv[1..]`,
while process.title on macOS rewrites argv[0] only, so the status could
never reach a Zed tab. name is immutable for a live process, and under
Bun the setter does not change argv at all. Zed users see the status in
the terminal breadcrumbs; a Zed tab indicator needs a Zed-side feature.

Test the real event seams (agent_start, agent_end, compaction_start,
compaction_end while streaming, stop) through handleEvent instead of
calling the setter directly, so deleting the wiring fails the suite, and
restore process.title in afterEach.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant